{
  LW XPanel -- LightWave XPanel Services

  Based on lwxpanel.h which is:
  Copyright 1999, NewTek, Inc.
}

{
  Copyright 2012, Jameel Halabi

  This unit is part of the BlaiseWave wrapper,
  which is licensed under the BSD 2-Clause license (see licenses/license.txt).
}


unit LW_XPanel;

{$mode objfpc}{$H+}

interface

uses
  LW_Types;

const
  LWXPANELFUNCS_GLOBAL = 'LWXPanel 2';

type
  PLWXPanelHint = Pointer;
  PXpH          = Pointer;

const
  // Hint Tags
  XPTAG_END           = PXpH(0)        ;
  XPTAG_NULL          = PXpH(0)        ;
  XPTAG_CALL          = PXpH($DD002)   ;
  XPTAG_NEST          = PXpH($101)     ;

  XPTAG_LABEL         = PXpH($3D000B03);
  XPTAG_CLASS         = PXpH($3D000C02);
  XPTAG_ADD           = PXpH($3D000D03);
  XPTAG_DELETE        = PXpH($3D000E01);
  XPTAG_CHGNOTIFY     = PXpH($3D000F01);
  XPTAG_FOCUS         = PXpH($3D001201);
  XPTAG_AUTORESTORE   = PXpH($3D001481);
  XPTAG_COLORSPACE    = PXpH($3D001503);
  XPTAG_DESTROYNOTIFY = PXpH($3D001302);

  XPTAG_VALUE         = PXpH($3D006502);
  XPTAG_LINK          = PXpH($3D006681);
  XPTAG_IMMUPD        = PXpH($3D006781);
  XPTAG_TRACK         = PXpH($3D006802);
  XPTAG_ORIENT        = PXpH($3D00CB02);

  XPTAG_MIN           = PXpH($3D014002);
  XPTAG_MAX           = PXpH($3D014102);
  XPTAG_STEP          = PXpH($3D014202);
  XPTAG_RANGE         = PXpH($3D014304);
  XPTAG_HARDMINMAX    = PXpH($3D014703);
  XPTAG_CLRMINMAX     = PXpH($3D014803);
  XPTAG_SENS          = PXpH($3D014402);

  XPTAG_BUTNOTIFY     = PXpH($3D015F02);
  XPTAG_POPCMDFUNC    = PXpH($3D016002);
  XPTAG_POPFUNCS      = PXpH($3D016203);
  XPTAG_INTXFORM      = PXpH($3D016303);
  XPTAG_DRAWCBFUNC    = PXpH($3D016502);
  XPTAG_ZOOMCBFUNC    = PXpH($3D016603);
  XPTAG_TEXTXFORMFUNC = PXpH($3D016802);

  XPTAG_STRLIST       = PXpH($3D014503);
  XPTAG_VECLABEL      = PXpH($3D017202);
  XPTAG_CTRLFRONT     = PXpH($3D017301);
  XPTAG_CTRLCFG       = PXpH($3D017403);
  XPTAG_XREQCFG       = PXpH($3D019105);

  XPTAG_ALIAS         = PXpH($3D01F481);
  XPTAG_UNALIAS       = PXpH($3D01F581);
  XPTAG_ENABLE        = PXpH($3D01F984);

  XPTAG_GROUP         = PXpH($3D01FE81);
  XPTAG_ORDER         = PXpH($3D01FF81);
  XPTAG_STACK         = PXpH($3D020983);
  XPTAG_TABS          = PXpH($3D020A81);

  XPTAG_LEFT          = PXpH($3D021280);
  XPTAG_NARROW        = PXpH($3D021380);
  XPTAG_DIVADD        = PXpH($3D021481);
  XPTAG_DIVREM        = PXpH($3D021581);
  XPTAG_BORDER        = PXpH($3D021501);

  XPTAG_DLOGTYPE      = PXpH($3D02BD01);
  XPTAG_ALIGN_WIDTH   = PXpH($3D021680);
  XPTAG_ALIGN_MINIS   = PXpH($3D021701);

// Hint Macros

{
  Variable name guide
  IDs are unsigned int > 0x8000
       CID  = ControlID
       GID  = GroupID
       VID  = ValueID
       CGID = Either a ControlID or GroupID acceptable
       ID   = General ID variable; use depends on context

  #define XpEND                           XPTAG_END
  #define XpCALL(ref)                     XPTAG_CALL, XPTAG_NULL, PXpH(ref)
  #define XpSUBCALL(id,ref)               XPTAG_CALL, PXpH(id), PXpH(ref)
  #define XpNEST(id)                      XPTAG_NEST, PXpH(id)

  /* Configuration Hints */
  #define XpLABEL(id,str)                 XPTAG_LABEL, PXpH(id), PXpH(str), XPTAG_NULL
  #define XpCLASS(id,cl)                  XPTAG_CLASS, PXpH(id), PXpH(cl)

  #define XpADD(id,cl,vid)                XPTAG_ADD, PXpH(id), PXpH(cl), PXpH(vid)
  #define XpDELETE(id)                    XPTAG_DELETE, PXpH(id)

  #define XpCHGNOTIFY(func)               XPTAG_CHGNOTIFY, PXpH(func)
  #define XpFOCUS(cid)                    XPTAG_FOCUS, PXpH(cid)
  #define XpRESTORE(vid)                  XPTAG_AUTORESTORE, PXpH(1), PXpH(vid), XPTAG_NULL
  #define XpRESTORE_()                    XPTAG_AUTORESTORE, PXpH(1)
  #define XpRESTORE_ON                    XPTAG_AUTORESTORE, PXpH(1), XPTAG_NULL
  #define XpRESTORE_OFF                   XPTAG_AUTORESTORE, PXpH(0), XPTAG_NULL
  #define XpCOLORSPACE(id,str)            XPTAG_COLORSPACE, PXpH(id), PXpH(str), XPTAG_NULL
  #define XpDESTROYNOTIFY(func)           XPTAG_DESTROYNOTIFY, PXpH(func), XPTAG_NULL

  #define XpVALUE(dep,vid)                XPTAG_VALUE, PXpH(dep), PXpH(vid)
  #define XpLINK_(vid)                    XPTAG_LINK, PXpH(vid)
  #define XpLINK(vid,link)                XPTAG_LINK, PXpH(vid), PXpH(link), XPTAG_NULL
  #define XpIMMUPD(cid,did)               XPTAG_IMMUPD, PXpH(cid), PXpH(did), XPTAG_NULL
  #define XpIMMUPD_(cid)                  XPTAG_IMMUPD, PXpH(cid)
  #define XpTRACK(cid,track)              XPTAG_TRACK, PXpH(cid), PXpH(track)
  #define XpORIENT(cid,orient)            XPTAG_ORIENT, PXpH(cid), PXpH(orient)

  #define XpMIN(cid,min)                  XPTAG_MIN, PXpH(cid), PXpH(min)
  #define XpMAX(cid,max)                  XPTAG_MAX, PXpH(cid), PXpH(max)
  #define XpSTEP(cid,step)                XPTAG_STEP, PXpH(cid), PXpH(step)
  #define XpRANGE(cid,mn,mx,st)           XPTAG_RANGE, PXpH(cid), PXpH(mn), PXpH(mx), PXpH(st)
  #define XpHARDMINMAX(cid,mn,mx)         XPTAG_HARDMINMAX, PXpH(cid), PXpH(mn), PXpH(mx)
  #define XpCLRMINMAX(cid,mn,mx)          XPTAG_CLRMINMAX, PXpH(cid), PXpH(mn), PXpH(mx)
  #define XpSENS(cid,sens)                XPTAG_SENS, PXpH(cid), PXpH(sens)

  #define XpSTRLIST(cid,slist)            XPTAG_STRLIST, PXpH(cid), PXpH(slist), XPTAG_NULL
  #define XpVECLABEL(cid,slist)           XPTAG_VECLABEL, PXpH(cid), PXpH(slist)
  #define XpCTRLFRONT(cid)                XPTAG_CTRLFRONT, PXpH(cid)
  #define XpCTRLCFG(cid,opt)              XPTAG_CTRLCFG, PXpH(cid), XPTAG_NULL, PXpH(opt)
  #define XpXREQCFG(cid,mode,ttl,ftyp)    XPTAG_XREQCFG, PXpH(cid), PXpH(mode), PXpH(ttl), PXpH(ftyp), XPTAG_NULL

  /* Callbacks */
  #define XpBUTNOTIFY(cid,func)           XPTAG_BUTNOTIFY, PXpH(cid), PXpH(func)
  #define XpPOPCMDFUNC(cid,func)          XPTAG_POPCMDFUNC, PXpH(cid), PXpH(func)
  #define XpPOPFUNCS(cid,cnt,nam)         XPTAG_POPFUNCS, PXpH(cid), PXpH(cnt), PXpH(nam)
  #define XpINTXFORM(cid,cnt,ilist)       XPTAG_INTXFORM, PXpH(cid), PXpH(cnt), PXpH(ilist)
  #define XpPOPXFORM(cid,cnt,ilist)       XpINTXFORM(cid,cnt,ilist)
  #define XpCHOXFORM(cid,cnt,ilist)       XpINTXFORM(cid,cnt,ilist)
  #define XpDRAWCBFUNC(cid,func)          XPTAG_DRAWCBFUNC, PXpH(cid), PXpH(func)
  #define XpZOOMCBFUNC(cid,func,reg)      XPTAG_ZOOMCBFUNC, PXpH(cid), PXpH(func), PXpH(reg)
  #define XpTEXTXFORMFUNC(cid,func)       XPTAG_TEXTXFORMFUNC, PXpH(cid), PXpH(func)

  /* Relationships */
  #define XpALIAS_(id)                    XPTAG_ALIAS, PXpH(id)
  #define XpUNALIAS_(id)                  XPTAG_UNALIAS, PXpH(id)

  #define XpENABLE(vid,sub)               XPTAG_ENABLE, PXpH(vid), XPTAG_NULL, XPTAG_NULL, XPTAG_NULL, PXpH(sub), XPTAG_NULL
  #define XpENABLE_(vid)                  XPTAG_ENABLE, PXpH(vid), XPTAG_NULL, XPTAG_NULL, XPTAG_NULL
  #define XpENABLE_MAP_(vid,map)          XPTAG_ENABLE, PXpH(vid), XPTAG_NULL, XPTAG_NULL, PXpH(map)
  #define XpENABLEMSG_(vid,msg)           XPTAG_ENABLE, PXpH(vid), PXpH(msg), XPTAG_NULL, XPTAG_NULL
  #define XpENABLEMSG_MAP_(vid,map,msg)   XPTAG_ENABLE, PXpH(vid), PXpH(msg), XPTAG_NULL, PXpH(map)

  /* Layout Hints */
  #define XpGROUP_(gid)                   XPTAG_GROUP, PXpH(gid)
  #define XpORDER_(gid)                   XPTAG_ORDER, PXpH(gid)
  #define XpSTACK_(gid,vid)               XPTAG_STACK, PXpH(gid), PXpH(vid), XPTAG_NULL
  #define XpSTACK_MAP_(gid,vid,map)       XPTAG_STACK, PXpH(gid), PXpH(vid), PXpH(map)
  #define XpTABS_(gid)                    XPTAG_TABS, PXpH(gid)

  #define XpLEFT(gid)                     XPTAG_LEFT, PXpH(gid), XPTAG_NULL
  #define XpLEFT_()                       XPTAG_LEFT
  #define XpNARROW(gid)                   XPTAG_NARROW, PXpH(gid), XPTAG_NULL
  #define XpNARROW_()                     XPTAG_NARROW

  #define XpDIVADD(id)                    XPTAG_DIVADD, PXpH(id), XPTAG_NULL
  #define XpDIVADD_(id)                   XPTAG_DIVADD, PXpH(id)
  #define XpDIVREM(id)                    XPTAG_DIVREM, PXpH(id), XPTAG_NULL
  #define XpDIVREM_(id)                   XPTAG_DIVREM, PXpH(id)

  #define XpBORDER(typ)                   XPTAG_BORDER, PXpH(typ)
  #define XpDLOGTYPE(typ)                 XPTAG_DLOGTYPE, PXpH(typ)

  #define XpALIGN_WIDTH(gid)              XPTAG_ALIGN_WIDTH, PXpH(gid), XPTAG_NULL
  #define XpALIGN_WIDTH_()                XPTAG_ALIGN_WIDTH

  #define XpALIGN_MINIS(on)               XPTAG_ALIGN_MINIS, PXpH(on)
}

  // Panel Types
  LWXP_VIEW = 1;
  LWXP_FORM = 2;

  {
    Client Notification Event Types

    TRACK     - Value changes are in progress; e.g., mouse drag of a mini-slider
    VALUE     - Value has changed. Change could result for a
                mouse-up event, user hitting tab or enter, etc.
                These events are usually generated by controls
                which have an underlying value (e.g., "string")
    HIT       - Similar to value events but usually associated
                with NULL-based control types (vButton, etc.)
    FOCUS     - LWXPanel has gained user's attention
    LOSEFOCUS - LWXPanel lost user's attention
  }

  // enum LWXPEventTypes
  LWXPEVENT_TRACK     = 1;
  LWXPEVENT_VALUE     = 2;
  LWXPEVENT_HIT       = 3;
  LWXPEVENT_FOCUS     = 4;
  LWXPEVENT_LOSEFOCUS = 5;

  // enum LWXPRefreshCodes
  LWXPRC_NONE     = 0;
  LWXPRC_DFLT     = 1;
  LWXPRC_DRAW     = 2;
  LWXPRC_FULL     = 3;
  LWXPRC_REFORMAT = 4;

  // enum LWXPDialogTypes
  LWXPDLG_OKCANCEL = 2;  // ok(1)/cancel(0) (default panel type);
  LWXPDLG_DONE     = 3;  // done(1);
  LWXPDLG_OKONLY   = 4;  // ok(1);
  LWXPDLG_YESNO    = 5;  // yes(1)/no(0);
  LWXPDLG_YESNOALL = 6;  // yes(1)/no(0)/yes-to-all(2)/cancel(3).
  LWXPDLG_YESNOCAN = 7;  // yes(1)/no(0)/cancel(3);

  // enum sFileName modes
  LWXPREQ_LOAD = 0;
  LWXPREQ_SAVE = 1;
  LWXPREQ_DIR  = 2;

  // enum Border types
  LWXPBDR_NONE = 0;
  LWXPBDR_UP   = 1;
  LWXPBDR_DOWN = 2;

  // Control configuration

  // Thumbnail Control
  THUM_SML         = 1 shl 0;
  THUM_MED         = 1 shl 1;
  THUM_LRG         = 1 shl 2;
  THUM_XLG         = 1 shl 3;
  THUM_SNGL        = 1 shl 4;

  THUM_SQ          = 1 shl 16;
  THUM_NTSC        = 1 shl 17;
  THUM_35MM        = 1 shl 18;
  THUM_PORT        = 1 shl 19;
  THUM_WIDE        = 1 shl 20;
  THUM_ANAW        = 1 shl 21;
  THUM_EURO        = 1 shl 22;

  THUM_FULL        = 1 shl 31 ;
  THUM_LAND        = THUM_NTSC;

  THUM_BORDER_UP   = 1 shl 9                ;
  THUM_BORDER_DOWN = 1 shl 10               ;
  THUM_BORDER_NONE = (1 shl 9) or (1 shl 10);

  // Text transform modes
  // enum LWXPanelTextXFormMode
  LWXPTEXTXFORM_TODISPLAY   = 0;
  LWXPTEXTXFORM_FROMDISPLAY = 1;

type
  PLWXPanel = Pointer;

  // Controls
  PLWXPanelControl = ^TLWXPanelControl;
  TLWXPanelControl = record
    CID       : UInt32;
    Label_    : PChar ;
    CtrlClass : PChar ;
  end;

  // Data Description
  PLWXPanelDataDesc = ^TLWXPanelDataDesc;
  TLWXPanelDataDesc = record
    VID      : UInt32;
    Name     : PChar ;
    DataType : PChar ;
  end;

  // Draw Functions
  PLWXPDrArea = Pointer;

  PLWXPDrawFuncs = ^TLWXPDrawFuncs;
  TLWXPDrawFuncs = record
    DrawPixel    : procedure
                   (P                  : PLWXPDrArea;
                    C, X, Y            : Integer    ) ;
    DrawRGBPixel : procedure
                   (P                  : PLWXPDrArea;
                    R, G, B, X, Y      : Integer    ) ;
    DrawLine     : procedure
                   (P                  : PLWXPDrArea;
                    C, X, Y, X2, Y2    : Integer    ) ;
    DrawBox      : procedure
                   (P                  : PLWXPDrArea;
                    C, X, Y, W, H      : Integer    ) ;
    DrawRGBBox   : procedure
                   (P                  : PLWXPDrArea;
                    R, G, B            : Integer    ;
                    X, Y, W, H         : Integer    ) ;
    DrawBorder   : procedure
                   (P                  : PLWXPDrArea;
                    Indent, X, Y, W, H : Integer    ) ;
    TextWidth    : function
                   (P                  : PLWXPDrArea;
                    S                  : PChar      ) : Integer;
    TextHeight   : function
                   (P                  : PLWXPDrArea;
                    S                  : PChar      ) : Integer;
    DrawText     : procedure
                   (P                  : PLWXPDrArea;
                    S                  : PChar      ;
                    C, X, Y            : Integer    ) ;
  end;

  {
    Callback Prototypes
    The "Get" returns a pointer to the value for ValueID 'vid'.
    The pointer is then cast and dereferenced as needed.
    The "Set" is given a pointer to the value for the ValueID, 'vid'.
    The "Set" returns one of the above refresh flags where 'NONE'
    indicates 'vid' was unrecognized.
  }
  TLWXPanelGetFunc = function
                     (Inst : Pointer;
                      VID  : UInt32 ) : Pointer;

  TLWXPRefreshCode = Integer;
  TLWXPanelSetFunc = function
                     (Inst  : Pointer;
                      VID   : UInt32 ;
                      Value : Pointer) : TLWXPRefreshCode;

  {
    Destroy notification

    This is called _after_ destruction of the panel instance and is
    intended for cleanup of any panel specific allocations, etc.
    This is necessary when the panel was returned to the application
    by setting the LWInterface "panel" to a plugin created LWXPanelID.
    In such cases, the application may destroy the panel automatically.
    The panData argument is whatever was set using "setData (pan,0,panData)"
    to set the panel's userdata.

    If the callback is called, the client should not destroy the panel.
    If it is not called, the client should destroy its interface with
    the client is destroyed.
  }
  TLWXPanelDestroyNotifyFunc = procedure
                               (PanData : Pointer) ;

  // Event notification
  TLWXPanelChangeNotifyFunc = function
                              (Pan       : PLWXPanel;
                               CID       : UInt32   ;
                               VID       : UInt32   ;
                               EventType : Integer  ) : TLWXPRefreshCode;

  // Button click event notification
  TLWXPanelBtnClickFunc = procedure
                          (Pan : PLWXPanel;
                           CID : Integer  ) ;

  // Popup command
  TLWXPanelPopCmdFunc = procedure
                        (Pan   : PLWXPanel;
                         CID   : Integer  ;
                         CmdID : Integer  ) ;

  // Popup choice
  TLWXPanelPopCntFunc = function
                        (UserData : Pointer) : Integer;

  TLWXPanelPopNameFunc = function
                         (UserData : Pointer;
                          Idx      : Integer) : PChar;

  // Text transform function
  TLWXPanelTextXFormMode = Integer;
  TLWXPanelTextXFormFunc = function
                           (      Pan     : PLWXPanel             ;
                                  CID     : UInt32                ;
                            const String_ : PChar                 ;
                                  Mode    : TLWXPanelTextXFormMode) : PChar;

  // Draw Function
  TLWXPanelControlDrawFunc = procedure
                             (Pan  : PLWXPanel  ;
                              CID  : UInt32     ;
                              EG   : PLWXPDrArea;
                              W, H : Integer    ) ;
  TLWXPanelControlZoomFunc = procedure
                             (Pan        : PLWXPanel;
                              CID        : UInt32   ;
                              X, Y       : Integer  ;
                              Region     : PInteger ;
                              ClickCount : Integer  ) ;

  {
         GLOBAL SERVICE INTERFACE.
                 These are the functions required to create
                 and manipulate an LWXPanel.

    Version:     the version number of the interface.  Certain control types
                 or hints may not be available in older interfaces.

         SETUP FUNCTIONS

    Create:      construct a new panel of the given type from the control
                 description.  The type can be LWXP_VIEW or LWXP_FORM.

    Destroy:     free a panel.

    Describe:    define the data values for this panel.  The data description
                 contains the list of value IDs and their types.  If this is
                 a VIEW panel, then the get and set functions are required to
                 read and write the values from the opaque client instance.

    Hint:        apply a hint array to the panel.  This may be called multiple
                 times, but only while the panel is closed.

         USER DATA FUNCTIONS

    SetData:     set userdata for a control which will be passed to the
                 callbacks for that control.  A control ID of zero sets
                 the data for the whole panel. (NOTE: userdata for ID
                 zero is returned in the deestroy notification callback)

    GetData:     get the userdata for a control or the whole panel.

         PANEL VALUE FUNCTIONS
                 (a brief description)
                 The panel can present data as a VIEW or a FORM.
                 A VIEW panel is a "view" of a client owned data instance.
                 Therefore, the client must provide get and set methods to
                 allow the panel to directly update the data instance set
                 with viewInst.
                 A FORM panel, on the other hand, presents a collection of
                 data parameters where the data instance itself is owned by
                 the panel. The parameter values are accessed by the client
                 using the formGet and formSet methods.

    FormSet:     write a data value to a slot in a FORM panel.  The value
                 pointer should point to the new value for the entry, or
                 null for none.

    FormGet:     read the value from a slot in a FORM panel.  Null is returned
                 for slots that are unset.

    ViewInst:    set the instance pointer for a VIEW panel.  The values on the
                 panel will be read from the instance using the client's get
                 and set methods.

    ViewRefresh: "Refreshes" a VIEW panel by reloading control values from the
                 client data instance. Generally, this is reserved for use when
                 the client data instance is modified from an external source
                 other than the panel interface or through other operations
                 internal to the client.

         INTERACTION FUNCTIONS

    Post:        display the panel for modal interaction.  The panel will open
                 as a modal dialog and will not return control to the caller
                 until the user selects 'OK' or 'Cancel'.  The function returns
                 true or false, respectively for those cases.

    Open:        display the panel for non-modal interaction.  This function
                 returns true immediately and the panel stays open until the
                 user closes it.
  }

  // Global Services
  PLWXPanelFuncs = ^TLWXPanelFuncs;
  TLWXPanelFuncs = record
    Version : Integer       ;
    DrawF   : PLWXPDrawFuncs;

    Create      : function
                  (      Type_    : Integer          ;
                         CtrlDesc : PLWXPanelControl ) : PLWXPanel;
    Destroy     : procedure
                  (      Panel    : PLWXPanel        ) ;
    Describe    : procedure
                  (      Panel    : PLWXPanel        ;
                         DataDesc : PLWXPanelDataDesc;
                         Get      : TLWXPanelGetFunc ;
                         Set_     : TLWXPanelSetFunc ) ;
    Hint        : procedure
                  (      Panel    : PLWXPanel        ;
                         AnID     : UInt32           ;
                         Hints    : PLWXPanelHint    ) ;
    GetData     : function
                  (      Panel    : PLWXPanel        ;
                         DataID   : UInt32           ) : Pointer  ;
    SetData     : procedure
                  (      Panel    : PLWXPanel        ;
                         DataID   : UInt32           ;
                         Data     : Pointer          ) ;
    FormGet     : function
                  (      Panel    : PLWXPanel        ;
                         VID      : UInt32           ) : Pointer  ;
    FormSet     : procedure
                  (      Panel    : PLWXPanel        ;
                         VID      : UInt32           ;
                         Value    : Pointer          ) ;
    ViewInst    : procedure
                  (      Panel    : PLWXPanel        ;
                         Inst     : Pointer          ) ;
    ViewRefresh : procedure
                  (      Panel    : PLWXPanel        ) ;
    Post        : function
                  (      Panel    : PLWXPanel        ) : Integer  ;
    Open        : function
                  (      Panel    : PLWXPanel        ) : Integer  ;
    ViewRebuild : procedure
                  (      Panel    : PLWXPanel        ) ;
  end;

implementation

end.

